package mobi.zeedev.flyingsaucer.common.RegexModule;

import android.content.ContentValues;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv;
import mobi.zeedev.flyingsaucer.common.DataModule.MetaBeer;
import mobi.zeedev.flyingsaucer.common.RegexModule.impl.ParseException;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexUtil {

    public static final String stripSlashes(String in) {
        String ret = null;
        Pattern p = Pattern.compile("\\\\'");
        Matcher m = p.matcher(in);

        ret = m.replaceAll("'");
        return ret;
    }

    public static final void addNameProperties(String rawName, Map<String, Object> cb) {
        List<List<String>> result = regexMatchWithNull("(.*?) ?\\((.*?)\\)", null, rawName);


        if (result == null || result.isEmpty()) {
            cb.put(MetaBeer.RAW_NAME, rawName);
            cb.put(MetaBeer.NAME, rawName);
            cb.put(MetaBeer.DRAUGHT, true);
            cb.put(MetaBeer.BOTTLE, false);
            cb.put(MetaBeer.CAN, false);
            return;
        }
        List<String> res = result.get(0);

        String name = res.get(0);
        String subscript = res.get(1);
//		if (res.size() > 1) {
//			subscript = 
//		}

//		cb.put(MetaBeer.NAME, rawName.substring(0, rawName.length() - 6));
        cb.put(MetaBeer.NAME, name);
//		String subscript = rawName.substring(rawName.length() - 4, rawName.length() - 1);
        cb.put(MetaBeer.NAME_SUBSCRIPT, subscript);
        cb.put(MetaBeer.RAW_NAME, rawName);

        final String can = "can";
        final String btl = "btl";
        final String magnum = "magnum";
        final String cask = "cask";

        String substringLower = subscript.toLowerCase();

        if (subscript == null) {
//			cb.put(MetaBeer.NAME, rawName);
            cb.put(MetaBeer.DRAUGHT, true);
            cb.put(MetaBeer.BOTTLE, false);
            cb.put(MetaBeer.CAN, false);
        } else if (substringLower.equals(btl)) {
            cb.put(MetaBeer.DRAUGHT, false);
            cb.put(MetaBeer.BOTTLE, true);
            cb.put(MetaBeer.CAN, false);
        } else if (substringLower.equals(can)) {
            cb.put(MetaBeer.DRAUGHT, false);
            cb.put(MetaBeer.BOTTLE, false);
            cb.put(MetaBeer.CAN, true);
        } else if (substringLower.equals(cask)) {
            cb.put(MetaBeer.DRAUGHT, true);
            cb.put(MetaBeer.BOTTLE, false);
            cb.put(MetaBeer.CAN, false);
        } else if (substringLower.equals(magnum)) {
            cb.put(MetaBeer.DRAUGHT, false);
            cb.put(MetaBeer.BOTTLE, true);
            cb.put(MetaBeer.CAN, false);
        } else {
            cb.put(MetaBeer.DRAUGHT, true);
            cb.put(MetaBeer.BOTTLE, false);
            cb.put(MetaBeer.CAN, false);
        }


    }

    public static final <A, T> A regexProcess(String regexIn, String data, Integer flags, RegexHandler2<A, T> handler) {
        return handler.regexProcess(regexIn, data, flags);
    }

    public static final List<ContentValues> induceContentValuesList(List<Map<String, Object>> insertMap) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException {
        if (insertMap == null || insertMap.size() <= 0) {
            return new ArrayList<ContentValues>();
        }
        List<ContentValues> cvList = new ArrayList<ContentValues>(insertMap.size());
        for (Map<String, Object> subMap : insertMap) {
            if (subMap != null) {
                cvList.add(induceContentValues(subMap));
            }
        }

        return cvList;

    }

    public static final ContentValues induceContentValues(Map<String, Object> insertMap) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException {
        ContentValues cv = new ContentValues();
        Field f = cv.getClass().getDeclaredField("mValues");
        f.setAccessible(true);
        f.set(cv, insertMap);
        return cv;
    }

    @Deprecated
    public static final ContentValues induceContentValues2(Map insertMap) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException {
        ContentValues cv = new ContentValues();
        Field f = cv.getClass().getDeclaredField("mValues");
        f.setAccessible(true);
        f.set(cv, insertMap);
        return cv;
    }

    public static final void merge(Map<String, Object> namePropertyMap, String insertMethod, List<ContentValues> tastedList) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {

//		Map<String, String> nameDateMap = getNameDateMap();
        for (ContentValues cv : tastedList) {
            String rawName = cv.getAsString(MetaBeer.RAW_NAME);
            String dateValue = (String) namePropertyMap.get(rawName);

            if (insertMethod.equals("addStyleProperties")) {

                addStyleProperties(dateValue,cv);


            }   else if (insertMethod.equals("addDatePropertiesCP")) {

                addDatePropertiesCP(dateValue,cv);

            }

            //invoke insert method here
//            Method addMethod = RegexUtil.class.getMethod(insertMethod, String.class, ContentValues.class);

            //String styleValue...
//            addMethod.invoke(null, dateValue, cv);
//			RegexUtil.addDateProperties(namePropertyMap.get(rawName), cv);

        }

    }


    public static final void addStyleProperties(String rawStyle, ContentValues cb) {
        if (rawStyle != null && !rawStyle.equals("")) {
            cb.put(MetaBeer.STYLE_NAME, rawStyle);
        }
    }


    public static final void addDatePropertiesCP(String rawDate, ContentValues cb) {
        if (rawDate != null && !rawDate.equals("")) {
            Long curDate = MetaBeer.parseRawDateWebsite(rawDate);
            cb.put(FlyingSaucerConv.Members.MemberBeer.TASTED_DATE, curDate);
//			cb.put(MetaBeer.SIMPLE_DATE, MetaBeer.parseToSimpleDate(curDate));
//			cb.put(MetaBeer.TASTED, true);
        }
//		else {
//			cb.put(MemberBeer.TASTED_DATE, 0l);
//		}
    }

    public static List<List<String>> regexMatchWithNull(String regexIn, Integer flags, String data) {
        List<List<String>> o = null;
        try {
            o = regexMatch(regexIn, flags, data);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return o;
    }

    public static List<List<String>> regexMatch(String regexIn, Integer flags, String data) throws ParseException {
        List<List<String>> retList = new ArrayList<List<String>>();
        List<String> matchesList = null;

        Pattern p = flags != null ? Pattern.compile(regexIn, flags) : Pattern.compile(regexIn);

        Matcher m = p.matcher(data);

        try {

            while (m.find()) {
                MatchResult mr = m.toMatchResult();
                matchesList = new ArrayList<String>(3);
                //int c = mr.groupCount();

                for (int i = 1; i <= mr.groupCount(); i++) {
                    matchesList.add(mr.group(i));
                }
                retList.add(matchesList);
            }

        } catch (Exception e) {
            throw new ParseException("Problem with parsing data from website.", regexIn, flags, data, e);
        }
        return retList;
    }

    public static String regexSingleMatch(String regexIn, Integer flags, String data) throws ParseException {
        String ret = null;

        Pattern p = flags != null ? Pattern.compile(regexIn, flags) : Pattern.compile(regexIn);

        Matcher m = p.matcher(data);

        try {

            if (m.find()) {

                ret = m.group(1);
                if (ret == null) {
                    throw new ParseException("No match found for expression.", regexIn, flags, data, null);
                }

            } else {
                throw new ParseException("No match found for expression.", regexIn, flags, data, null);
            }

        } catch (Exception e) {
            throw new ParseException("Problem with parsing data from website.", regexIn, flags, data, e);
        }
        return ret;
    }

    public static String regexSingleMatchWithNull(String regexIn, Integer flags, String data) {
        String ret = null;
        try {
            ret = regexSingleMatch(regexIn, flags, data);
        } catch (ParseException e) {
//			e.printStackTrace();
        }
        return ret;
    }

    public static List<List<String>> regexMatch(String regexIn, String data) throws ParseException {
        return regexMatch(regexIn, null, data);
    }


}
